package compound.repository

import org.codehaus.groovy.grails.commons.ConfigurationHolder
import org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib
import resultset.CompoundResultSet
import compound.repository.entries.Compound

class DataExportService {

  boolean transactional = false
  def g = new ApplicationTagLib()
  //def response
  // Export service provided by Export plugin
  def exportService



  void exportTextSearch(def result, def response, Map params = [:]) {
    List fields = ["SNO", "DefaultName", "inchiHashKey"]
    String format = params.format

    Map labels = generateLabels(format, params)


    Map formatters = [:]
    Map parameters = ["query": params.query, "root": "Compounds"]

    response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
    response.setHeader("Content-disposition", "attachment; filename=Compound.${params.extension}")

    debug(params, response)

    //Logic to prepare Export to excel List : Start
    List resultList = new ArrayList();
    if (result.results != null && result.results.size() > 0) {
      CompoundResultSet c = null
      int count = 0;
      for (Compound compound: result.results) {
        c = new CompoundResultSet()

        c.SNO = ++count
        c.DefaultName = compound.getDefaultName()
        c.inchiHashKey = compound.inchiHashKey.completeKey
        c.id = compound.id

        resultList.add(c);
      }
    }
    //println "resultList :: ${resultList}"
    //Logic to prepare Export to excel List : End

    exportService.export(params.format, response.outputStream, resultList, fields, labels, formatters, parameters)
  }

  void exportDiscover(def result, def response, Map params = [:]) {
    //println "result :: ${result}"
    //println "result.results :: ${result}"

    List fields = ["SNO", "DefaultName", "inchiHashKey", "DiscoveredInText", "Origin", "Reference"]

    String format = params.format

    LinkedHashMap<String, String> labels = generateLabels(format, params)

    Map formatters = [:]
    Map parameters = [:]

    response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
    response.setHeader("Content-disposition", "attachment; filename=Compound.${params.extension}")

    debug(params, response)

    //Logic to prepare Export to excel List : Start
    List resultList = new ArrayList();
    if (result != null && result.size() > 0) {
      int count = 0;
      CompoundResultSet c = null
      for (Map map: result) {
        Compound compound = map.compound

        c = new CompoundResultSet()

        c.SNO = ++count
        c.DefaultName = compound.getDefaultName()
        c.inchiHashKey = compound.inchiHashKey.completeKey
        c.id = compound.id

        c.DiscoveredInText = map.hit
        c.Origin = map.resolver
        c.Reference = map.result

        resultList.add(c);

      }
    }
    //println "resultList :: ${resultList}"
    //Logic to prepare Export to excel List : End

    exportService.export(params.format, response.outputStream, resultList, fields, labels, formatters, parameters)
  }

  /**
   * generates the used labels
   * @param format
   * @param params
   * @return
   */
  protected LinkedHashMap<String, String> generateLabels(String format, Map params) {
    Map labels = null

    if (format.equalsIgnoreCase("XML")) {
      params.put("extension", "xml")
      labels = ["SNO": "SNO", "DefaultName": "Name", "inchiHashKey": "inchiHashKey", "DiscoveredInText": "DiscoveredInText", "Origin": "Origin", "Reference": "Reference"]
    } else {
      labels = ["SNO": "S No.", "DefaultName": "Name", "inchiHashKey": "InChi Hash Key", "DiscoveredInText": "Discovered in Text", "Origin": "Origin", "Reference": "Reference"]
    }
    return labels
  }

  void exportTransform(def transform, def response, Map params = [:]) {
    //println "result :: ${transform}"
    //println "result.results :: ${transform}"

    List fields = ["SNO", "DefaultName", "inchiHashKey", "Translation"]
    String format = params.format

    Map labels = generateLabels(format, params)


    Map formatters = [:]
    Map parameters = ["idValue": params.idValue, "from": params.from, "to": params.to]

    response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
    response.setHeader("Content-disposition", "attachment; filename=Compound.${params.extension}")

    debug(params, response)

    //Logic to prepare Export to excel List : Start
    List resultList = new ArrayList();
    if (transform != null && transform.size() > 0) {
      int count = 0;
      CompoundResultSet c = null
      for (Map map: transform) {
        Compound compound = map.compound
        c = new CompoundResultSet()

        c.SNO = ++count
        c.DefaultName = compound.getDefaultName()
        c.inchiHashKey = compound.inchiHashKey.completeKey
        c.id = compound.id
        c.Translation = splitPreeFix(params.to, map.result)

        resultList.add(c);
      }
    }
    //println "resultList :: ${resultList}"
    //Logic to prepare Export to excel List : End

    exportService.export(params.format, response.outputStream, resultList, fields, labels, formatters, parameters)
  }

  /**
   * simple debug statement
   * @param params
   * @param response
   */
  protected def debug(Map params, response) {
    println "\n\n\nparams.extension :: ${params.extension}"
    println "response.contentType :: ${response.contentType}"
    println "params.format :: ${params.format}"
    println "response.outputStream :: ${response.outputStream}"
    //println "result :: ${transform}"
    println "exportService :: ${exportService}"
  }

  void exportMassLookUp(def transform, def response, Map params = [:]) {
    //println "result :: ${transform}"
    //println "result.results :: ${transform}"

    List fields = ["SNO","From", "DefaultName", "inchiHashKey"]

    String format = params.format

    Map labels = generateLabels(format, params)

    def to = params.to
    def from = params.from
    def ids = params.ids

    // create lables : Start
    for (int liCnt = 0; liCnt < to.size(); liCnt++) {
      fields.add(to.get(liCnt))
      if (format.equalsIgnoreCase("XML")) {
        labels.put(to.get(liCnt), code: to.get(liCnt))
      } else {
        labels.put(to.get(liCnt), g.message(code: to.get(liCnt), default: to.get(liCnt), encodeAs: "HTML"))
      }

    }             
    // create lables : End

    Map formatters = [:]
    Map parameters = ["ids": ids, "from": from, "to": to]

    response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
    response.setHeader("Content-disposition", "attachment; filename=Compound.${params.extension}")

    debug(params, response)

    //Logic to prepare Export to excel List : Start
    List resultList = new ArrayList();
    if (transform != null && transform.size() > 0) {
      int count = 0;
      CompoundResultSet c = null
      for (Map map: transform) {
        Compound compound = map.compound

        c = new CompoundResultSet()
        c.SNO = ++count


        c.From = map.fromValue
        
        if (compound != null) {
          c.DefaultName = compound.getDefaultName()
          c.inchiHashKey = compound.inchiHashKey.completeKey
          c.id = compound.id
        }
        else {
          c.DefaultName = "None"
          c.inchiHashKey = "None"
          c.id = "None"
        }

        HashMap lMap = (map.result);
        for (int liCnt = 0; liCnt < to.size(); liCnt++) {
          String keyname = to.get(liCnt)
          def lResult = lMap.get(keyname.toString().trim())
          //m.put(keyname,splitPreeFix(keyname,lResult))

          c."${keyname}" = splitPreeFix(keyname, lResult)
        }

        resultList.add(c);

        //println "${m}"
        //resultList.add(m);
      }
    }
    //Logic to prepare Export to excel List : End

    exportService.export(params.format, response.outputStream, resultList, fields, labels, formatters, parameters)
  }

  /**
   * This method is used to split prifix of the data like
   * inputData is "compound.repository.entries.Synonym: Flavin adenine dinucleotide"
   * result will be "Flavin adenine dinucleotide"
   */
  String splitPreeFix(String keyname, def inputData) {
    String resultStr = "";
    if (inputData != null) {
      if (inputData instanceof Collection) {
        if (inputData.size() > 0) {
          if (keyname.toString().equalsIgnoreCase("links")) {
            inputData.each { s ->

              if (resultStr.length() == 0) {
                resultStr = s.toString()
              }
              else {
                resultStr = resultStr + ", " + s.toString()
              }

            }

          } else {

            inputData.each { s ->

              def res = s.toString().split(":")
              if (resultStr.length() == 0) {
                resultStr = res[1] ? res[1] : res[0]
              }
              else {
                resultStr = resultStr + ", " + (res[1] ? res[1] : res[0])
              }

            }

          }
        }
      } else {

        resultStr = inputData.toString();
      }
    }

    return resultStr;
  }
}